(function (angular) {
  'use strict';

  angular
    .module('fs.modal', ['ui.bootstrap', 'modalTemplate'])
    .directive('fsDraggable', draggableDirevtive)
    .directive('fsResizeable', resizeableDirevtive)
    .controller('messageDialogsController', messageDialogsController)
    .provider('modalService', modalServiceProvider);

  angular.module("modalTemplate", []).run($templateCache);

  draggableDirevtive.$inject = ['$document', '$timeout'];
  function draggableDirevtive($document, $timeout) {
    return {
      restrict: 'A',
      link: function ($scope, $element, $attr) {
        var startX = 0, startY = 0, x = 0, y = 0, initialized = false, dialog;
        initDrag(1);
        function initDrag(count) {
          var dialogEl, titleEl, title;
          dialogEl = $element[0];// $document[0].querySelector("div[index='" + $attr.index + "'].modal");
					/*
					 * if (!dialogEl) { return; }
					 */
          titleEl = dialogEl.querySelector(".modal-header");
					/*
					 * if (!dialogEl || !titleEl) { if (count <= 20) { $timeout(function() { initDrag(++count); }, 100); } return; }
					 */
          dialog = angular.element(dialogEl);
          title = angular.element(titleEl);
          title.css({
            position: 'relative',
            cursor: 'move'
          });

          title.on('mousedown', function (event) {
            // Prevent default dragging of selected content
            event.preventDefault();
            if (!initialized) {
              x = dialogEl.offsetLeft;
              y = dialogEl.offsetTop;
              initialized = true;
            }
            startX = event.clientX - x;
            startY = event.clientY - y;
            $document.on('mousemove', mouseMove);
            $document.on('mouseup', mouseUp);
          });
        }

        function mouseMove(event) {
          var bodyElement = $document[0].querySelector('body');
          var maxY = bodyElement.offsetHeight - startY - 20;
          var maxX = bodyElement.offsetWidth - startX - 20;
          y = event.clientY - startY;
          x = event.clientX - startX;
          if (x < 0) {
            x = 0;
          }
          if (x > maxX) {
            x = maxX;
          }

          if (y < -20) {
            y = -20;
          }
          if (y > maxY) {
            y = maxY;
          }
          $timeout(function () {
            dialog.css({
              left: x + 'px',
              top: y + 'px'
            });
          }, 0, false);
        }

        function mouseUp() {
          $document.off('mousemove', mouseMove);
          $document.off('mouseup', mouseUp);
        }
      }
    };
  }

  resizeableDirevtive.$inject = ['$document', '$timeout'];
  function resizeableDirevtive($document, $timeout) {
    return {
      restrict: 'A',
      link: function ($scope, $element, $attr) {
        var startX = 0, startY = 0, dialogWidth, contentBodyWidth, contentBodyHeight, dialogEl, dialog, contentBodyEl, contentBody, right, bright, bleft, disableReszie = 0;
        initResize();
        function initResize() {
          var rightEL, brightEl, bleftEl, dialogWindowEl, contentEl, content;
          dialogWindowEl = $element[0];// $document[0].querySelector("div[index='" + $attr.index + "'].modal");
          if (!dialogWindowEl) {
            return;
          }
          dialogEl = dialogWindowEl.querySelector(".modal-dialog");
          if (!dialogEl) {
            return;
          }
          contentEl = dialogWindowEl.querySelector(".app-modal-content");
          if (!contentEl) {
            return;
          }
          contentBodyEl = contentEl.querySelector(".modal-body");
          if (!contentBodyEl) {
            return;
          }

          dialog = angular.element(dialogEl);
          content = angular.element(contentEl);
          contentBody = angular.element(contentBodyEl);

          content.append("<div class=\"resize-right\"></div>");
          content.append("<div class=\"resize-bottom-right\"></div>");
          content.append("<div class=\"resize-bottom-left\"></div></div>");

          rightEL = contentEl.querySelector(".resize-right");
          brightEl = contentEl.querySelector(".resize-bottom-right");
          bleftEl = contentEl.querySelector(".resize-bottom-left");

          right = angular.element(rightEL);
          bright = angular.element(brightEl);
          bleft = angular.element(bleftEl);

          right.on('mousedown', function (event) {
            // Prevent default dragging of selected content
            event.preventDefault();
            dialogWidth = dialogEl.offsetWidth;
            contentBodyWidth = contentBodyEl.offsetWidth;
            contentBodyHeight = contentBodyEl.offsetHeight;
            startX = event.clientX;
            startY = event.clientY;
            disableReszie = 1;
            $document.on('mousemove', mouseHorizontalMove);
            $document.on('mouseup', mouseUp);
          });

          bleft.on('mousedown', function (event) {
            // Prevent default dragging of selected content
            event.preventDefault();
            dialogWidth = dialogEl.offsetWidth;
            contentBodyWidth = contentBodyEl.offsetWidth;
            contentBodyHeight = contentBodyEl.offsetHeight;
            startX = event.clientX;
            startY = event.clientY;
            disableReszie = 2;
            $document.on('mousemove', mouseVerticalMove);
            $document.on('mouseup', mouseUp);
          });

          bright.on('mousedown', function (event) {
            // Prevent default dragging of selected content
            event.preventDefault();
            dialogWidth = dialogEl.offsetWidth;
            contentBodyWidth = contentBodyEl.offsetWidth;
            contentBodyHeight = contentBodyEl.offsetHeight;
            startX = event.clientX;
            startY = event.clientY;
            disableReszie = 0;
            $document.on('mousemove', mouseMove);
            $document.on('mouseup', mouseUp);

          });
        }

        function mouseHorizontalMove(event) {
          mouseMove(event);
        }

        function mouseVerticalMove(event) {
          mouseMove(event);
        }

        function mouseMove(event) {
          dialogWidth = disableReszie != 2 ? (dialogWidth + event.clientX - startX) : dialogWidth;
          contentBodyWidth = disableReszie != 2 ? (contentBodyWidth + event.clientX - startX) : contentBodyWidth;
          contentBodyHeight = disableReszie != 1 ? (contentBodyHeight + event.clientY - startY) : contentBodyHeight;
          startX = event.clientX;
          startY = event.clientY;
          $timeout(function () {
            dialog.css({
              width: dialogWidth + 'px',
            });
            contentBody.css({
              width: contentBodyWidth + 'px',
              height: contentBodyHeight + 'px'
            });
          }, 0, false);
        }

        function mouseUp() {
          $document.off('mousemove', mouseMove);
          $document.off('mousemove', mouseVerticalMove);
          $document.off('mousemove', mouseHorizontalMove);
          $document.off('mouseup', mouseUp);
        }
      }
    };
  }

  messageDialogsController.$inject = ['$rootScope', '$scope', '$timeout', '$uibModalInstance', '$translate', 'dialogsOptions', 'modalService'];
  function messageDialogsController($rootScope, $scope, $timeout, $uibModalInstance, $translate, dialogsOptions, modalService) {
    var ctrl = this, dialogMessages, resultMessages = [];
    ctrl.title = dialogsOptions.title;
    $rootScope.$uibModalInstance = $uibModalInstance;
    // support the i18n message which has the param {0}, {1}and etc.
    dialogMessages = angular.copy(dialogsOptions.messages);
    angular.forEach(dialogMessages, function (message, index) {
      if (message && angular.isString(message))
        dialogMessages[index] = message.replace(new RegExp("&lt", 'g'), "<").replace(new RegExp("&gt", 'g'), ">");
      var paramObj = {}, args = message.args, msg = message.msg;
      if (msg != undefined && args != undefined) {
        if (!angular.isArray(args)) {
          var newArray = [];
          newArray.push(args);
          args = newArray;
        }
        $translate(args).then(function (objs) {
          angular.forEach(args, function (key, index) {
            paramObj['p' + index] = objs[args[index]];
          });
          $translate(msg, paramObj).then(function (msg) {
            resultMessages.push(msg);
            ctrl.messages = resultMessages;
          }, function (msg) {
            resultMessages.push(msg);
            ctrl.messages = resultMessages;
          });
        }, function () {
          $translate(msg, paramObj).then(function (msg) {
            resultMessages.push(msg);
            ctrl.messages = resultMessages;
          }, function (msg) {
            resultMessages.push(msg);
            ctrl.messages = resultMessages;
          });
        });
      } else {
        ctrl.messages = dialogMessages;
      }
    });

    ctrl.redirections = dialogsOptions.redirections;
    if (dialogsOptions.bottomDefaultBtn == undefined)
      dialogsOptions.bottomDefaultBtn = true;
    if (dialogsOptions.bottomOkBtn)
      dialogsOptions.bottomDefaultBtn = false;
    ctrl.dialogsOptions = dialogsOptions;
    ctrl.close = function () {
      if (!dialogsOptions.btnCallback || !dialogsOptions.btnCallback['close'] || dialogsOptions.btnCallback['close']() !== false) {
        $uibModalInstance.dismiss();
      }
    };
    ctrl.ok = function () {
      if (!dialogsOptions.btnCallback || !dialogsOptions.btnCallback['ok'] || dialogsOptions.btnCallback['ok'](true) !== false) {
        $uibModalInstance.close();
      }
    };
    ctrl.promptOk = function () {
      if (!ctrl.promptMessage) {
        modalService.openErrorDialogs({
          messages: ['title.dialogs.comments.required']
        });
        return;
      }
      if (!dialogsOptions.btnCallback || !dialogsOptions.btnCallback['ok'] || dialogsOptions.btnCallback['ok'](ctrl.promptMessage) !== false) {
        $uibModalInstance.close();
      }
    };
    ctrl.promptOkAndCloseButtons = [{
      "name": "close",
      "label": "button.text.close",
      "type": "button",
      "btnClass": "btn-default",
      "options": {
        "icon": "close",
        "callback": {
          "click": "vm.close"
        }
      },
      "btnScope": $scope
    }, {
      "name": "promptOk",
      "label": "button.text.ok",
      "type": "button",
      "btnClass": "btn-primary",
      "options": {
        "icon": "ok",
        "callback": {
          "click": "vm.promptOk"
        }
      },
      "btnScope": $scope
    }

    ];
    ctrl.okAndCloseButtons = [{
      "name": "close",
      "label": "button.text.cancel",
      "type": "button",
      "btnClass": "btn-default",
      "options": {
        "icon": "close",
        "callback": {
          "click": "vm.close"
        }
      },
      "btnScope": $scope
    }, {
      "name": "ok",
      "label": "button.text.confirm",
      "type": "button",
      "btnClass": "btn-primary",
      "options": {
        "icon": "ok",
        "callback": {
          "click": "vm.ok"
        }
      },
      "btnScope": $scope
    }];
    ctrl.closeButtons = [{
      "name": "close",
      "label": "button.text.close",
      "type": "button",
      "btnClass": "btn-primary",
      "options": {
        "icon": "close",
        "callback": {
          "click": "vm.close"
        }
      },
      "btnScope": $scope
    }];
    ctrl.okButtons = [{
      "name": "ok",
      "label": "button.text.ok",
      "type": "button",
      "btnClass": "btn-primary",
      "options": {
        "icon": "ok",
        "callback": {
          "click": "vm.ok"
        }
      },
      "btnScope": $scope
    }];
    ctrl.redirect = function (redirection) {
      if (redirection.state) {
        $scope.go(redirection.state, redirection.params);
      }
      $uibModalInstance.dismiss();
    };
    ctrl.jump = function (redirection) {
      if (redirection.jump && angular.isFunction(redirection.jump)) {
        redirection.jump();
      } else if (redirection.state) {
        $scope.go(redirection.state, redirection.params);
      }
      $uibModalInstance.dismiss();
    };
    if (dialogsOptions.autoClose === true) {
      $uibModalInstance.rendered.then(function () {
        $timeout(function () {
          if (!dialogsOptions.cancelAutoClose) {
            ctrl.close();
          }
        }, dialogsOptions.autoCloseInterval * 1000, false);
      }, angular.noop);
    }
  }

  modalServiceProvider.$inject = [];
  function modalServiceProvider() {
    var provider = this;
    provider.dialogsModules = {};
    provider.loadingCount = 0;
    provider.loadingInstance = null;
    provider.loadingOptions = {
      // windowTemplateUrl : 'uib/template/modal/window.html',
      template: '<div class="icon-loading"></div>\n',
      size: 'sm',
      backdrop: 'static',
      keyboard: false,
      animation: false
    };
    provider.setDialogsModule = function (name, options) {
      provider.dialogsModules[name] = options;
    };
    provider.modalOptions = {
      size: 'lg',
      level: 'info',
      blocked: false,
      backdrop: 'static',
      keyboard: true,
      animation: true
      // windowTemplateUrl : 'pti/template/modal/window.html',
      // appendTo : provider.appendTo,
      // scope : provider.scope
      // backdropClass: '',
      // controller: '',
      // controllerAs: '',
      // openedClass:'',
      // resolve:{},
      // template: '',
      // templateUrl: '',
      // windowClass: '',
      // resolve : object or function
    };
    provider.$get = modalService;
    modalService.$inject = ['$rootScope', '$uibModal', '$uibPosition', '$window', '$document', '$q', '$log', '$timeout', 'routerService', 'hotkeys'];
    function modalService($rootScope, $uibModal, $uibPosition, $window, $document, $q, $log, $timeout, routerService, hotkeys) {
      provider.modalOptions.scope = $rootScope;
      provider.modalOptions.appendTo = angular.element($document[0].querySelector('.modal-container'));
      function moveToCenter() {
        var modalElements = $document[0].querySelectorAll('.dialogModal'), modal, top, left;
        angular.forEach(modalElements, function (modalElement) {
          var modalContent, css = {};
          move(1);
          function move(count) {
            modalContent = modalElement.querySelector('.modal-content');
            top = ($window.innerHeight - modalElement.offsetHeight) * 2 / 5 / $window.innerHeight * 100;
            left = ($window.innerWidth - modalElement.offsetWidth) / 2 / $window.innerWidth * 100;
            if (top == 0 || !modalContent) {
              if (count <= 20) {
                $timeout(function () {
                  move(++count);
                }, 10, false);
              }
              return;
            }
            if (top <= 0) {
              css.top = '30px';
            } else {
              css.top = top + '%';
            }
            if (left > 0) {
              css.left = left + '%';
            }
            modal = angular.element(modalElement);
            modal.css(css);
          }
        });
      }

      function openLoading() {
        if (!provider.loadingInstance) {
          provider.loadingOptions.appendTo = angular.element($document[0].querySelector('.modal-container'));
          provider.loadingInstance = openModalDialogs(provider.loadingOptions);
          provider.loadingInstance.closed.then(function (arg) {
            provider.loadingInstance = null;
            provider.loadingCount = 0;
          });
          ++provider.loadingCount;
        } else {
          ++provider.loadingCount;
        }
      }

      function closeLoading() {
        if (provider.loadingInstance) {
          --provider.loadingCount;
          if (provider.loadingCount <= 0 && !provider.loadingInstance._closing) {
            provider.loadingInstance.close();
          }
        }
      }

      function openModalDialogs(modalOptions) {
        var dialogsInstance, modalOpener;
        hotkeys.pause(true);
        modalOptions.backdrop = !modalOptions.backdrop ? 'static' : modalOptions.backdrop;
        dialogsInstance = $uibModal.open(modalOptions);
        dialogsInstance.closed.then(function (arg) {
          modalOpener = $document[0].activeElement;
          hotkeys.unpause(true);
          if (modalOpener && modalOpener.blur) {
            modalOpener.blur();
          }
        });
        dialogsInstance.rendered.then(function () {
          var modalBackdrop = $document[0].querySelector('modal-backdrop');
          if (modalBackdrop) {
            modalBackdrop = angular.element(modalBackdrop);
            modalBackdrop.css({
              'z-index': modalBackdrop.css('z-index') - 10
            });
          }
          moveToCenter();
        }, angular.noop);
        return dialogsInstance;
      }
      function openDialogs(modalOptions) {
        var dialogsInstance;
        hotkeys.pause(true);
        if (modalOptions.blocked == true) {
          modalOptions.backdrop = !modalOptions.backdrop ? 'static' : modalOptions.backdrop;
        } else {
          modalOptions.backdrop = false;
        }
        dialogsInstance = $uibModal.open(modalOptions);
        dialogsInstance.closed.then(function (arg) {
          var modalOpener = $document[0].activeElement;
          hotkeys.unpause(true);
          if (modalOpener && modalOpener.blur) {
            modalOpener.blur();
          }
        });
        dialogsInstance.rendered.then(moveToCenter, angular.noop);
        return dialogsInstance;
      }
      function openWarningDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption;
        options.title = options.title || 'title.dialogs.warning';
        options.level = options.level || 'warning';
        options.icon = options.icon || 'warning';
        options.messages = options.messages || [];
        defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/messages.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.size = options.size || [600, 120];
        modalOptions.blocked = options.blocked;
        if (modalOptions.size && angular.isArray(modalOptions.size)) {
          options.bodyStyle = {
            width: modalOptions.size[0] + 'px',
            height: modalOptions.size[1] + 'px'
          };
        }
        dialogsInstance = openDialogs(modalOptions);
        return dialogsInstance;
      }
      function openAcknowledgeDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/acknowledge.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        options.title = options.title || 'title.dialogs.acknowledge';
        options.messages = options.messages || [];
        options.level = 'info';
        options.icon = 'complete';
        options.windowTopClass = 'fade-out';
        options.animation = false;
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.size = options.size || [600, 120];
        modalOptions.level = options.level;
        if (modalOptions.size && angular.isArray(modalOptions.size)) {
          options.bodyStyle = {
            width: modalOptions.size[0] + 'px',
            height: modalOptions.size[1] + 'px'
          };
        }
        dialogsInstance = openModalDialogs(modalOptions);
        return dialogsInstance;
      }
      function openJumpDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/jump.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        options.title = options.title || 'title.dialogs.acknowledge';
        options.messages = options.messages || [];
        options.level = 'info';
        options.icon = 'complete';
        options.windowTopClass = 'fade-out';
        options.animation = false;
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.size = options.size || [600, 120];
        modalOptions.level = options.level;
        if (modalOptions.size && angular.isArray(modalOptions.size)) {
          options.bodyStyle = {
            width: modalOptions.size[0] + 'px',
            height: modalOptions.size[1] + 'px'
          };
        }
        dialogsInstance = openModalDialogs(modalOptions);
        return dialogsInstance;
      }
      function openErrorDialogs(options) {
        var dialogsInstance;
        options.title = options.title || 'title.dialogs.error';
        options.autoClose = (options.autoClose == true);
        options.autoCloseInterval = options.autoCloseInterval || 3;
        options.level = 'error';
        options.icon = 'failed';
        dialogsInstance = openWarningDialogs(options);
        return dialogsInstance;
      }
      function openInfoDialogs(options) {
        var dialogsInstance;
        options.title = options.title || 'title.dialogs.info';
        options.autoClose = (options.autoClose == true);
        options.autoCloseInterval = options.autoCloseInterval || 3;
        options.level = 'info';
        options.icon = 'regular';
        dialogsInstance = openWarningDialogs(options);
        return dialogsInstance;
      }
      function openSuccessDialogs(options) {
        var dialogsInstance;
        options.title = options.title || 'title.dialogs.success';
        options.autoClose = (options.autoClose == true);
        options.autoCloseInterval = options.autoCloseInterval || 3;
        options.level = 'success';
        options.icon = 'success';
        dialogsInstance = openWarningDialogs(options);
        return dialogsInstance;
      }
      // for log dialog
      function openLogDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/logMessages.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        options.title = options.title || 'title.dialogs.info';
        options.messages = options.messages || [];
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.level = 'info';
        dialogsInstance = openDialogs(modalOptions);
        return dialogsInstance;
      }
      function openConfirmDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/confirmMessages.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        options.title = options.title || 'title.dialogs.confirm';
        options.level = options.level || 'info';
        if (options.level == 'info') {
          options.icon = options.icon || 'regular';
        } else if (options.level == 'warning') {
          options.icon = options.icon || 'warning';
        } else if (options.level == 'success') {
          options.icon = options.icon || 'success';
        } else if (options.level == 'error') {
          options.icon = options.icon || 'failed';
        } else {
          options.icon = 'failed';
        }
        options.messages = options.messages || [];
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.size = options.size || [600, 120];
        modalOptions.blocked = true;
        if (modalOptions.size && angular.isArray(modalOptions.size)) {
          options.bodyStyle = {
            width: modalOptions.size[0] + 'px',
            height: modalOptions.size[1] + 'px'
          };
        }
        dialogsInstance = openModalDialogs(modalOptions);
        return dialogsInstance;
      }
      function openPromptDialogs(options) {
        var dialogsInstance, modalOptions, defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/promptInput.html',
          controller: 'messageDialogsController',
          controllerAs: 'vm',
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsOptions: function () {
              return options;
            }
          }
        };
        options.title = options.title || 'title.dialogs.prompt';
        options.messages = options.messages || [];
        options.level = options.level || 'info';
        options.icon = options.icon || 'regular';
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.size = [400, 120];
        modalOptions.blocked = true;
        if (modalOptions.size && angular.isArray(modalOptions.size)) {
          options.bodyStyle = {
            width: modalOptions.size[0] + 'px',
            height: modalOptions.size[1] + 'px'
          };
        }
        dialogsInstance = openModalDialogs(modalOptions);
        return dialogsInstance;
      }
      function openCustomDialogs(options) {
        var dialogsInstance, modalOptions, dialogsModule, defaultOption, dependentFiles, layoutConfig, i18nConfig, validatorConfig, authorizationConfig;
        var cacheLayout = false, cacheResource = false, cacheAuthorization = false, cacheValidationRule = false;
        dialogsModule = angular.merge({}, provider.dialogsModules[options.dialogsModule]);
        dialogsModule.disableButton = function ($event) {
          var btn = ($event.srcElement || $event.target).parentElement;
          if (btn.disabled) {
            return false;
          }
          btn.disabled = true;
          $timeout(function () {
            btn.disabled = false;
          }, 500, false);
        };
        if (dialogsModule.templateUrl) {
          dialogsModule.templateUrl = dialogsModule.templateUrl.replace('${theme}', routerService.getTheme());
        }
        dependentFiles = dialogsModule.dependentFiles;
        layoutConfig = dialogsModule.layoutConfig;
        i18nConfig = dialogsModule.i18nConfig;
        validatorConfig = dialogsModule.validatorConfig;
        authorizationConfig = dialogsModule.authorizationConfig;
        function getFormValidateMessages(formCtrls) {
          var errors = {};
          angular.forEach(formCtrls, function (formCtrl) {
            if (formCtrl.validateErrors) {
              angular.merge(errors, formCtrl.validateErrors);
            }
            if (formCtrl._formCtrls) {
              angular.merge(errors, getFormValidateMessages(formCtrl._formCtrls));
            }
          });
          return angular.equals({}, errors) ? null : errors;
        }
        // show error Messages if the form is invalid.
        dialogsModule.showErrorMessages = function (topFormCtrl) {
          var errors = getFormValidateMessages([topFormCtrl]);
          if (errors) {
            openErrorDialogs({
              'title': '',
              'messages': errors
            });
          }
        };
        dependentFileFn.$inject = ['$ocLazyLoad'];
        function dependentFileFn($ocLazyLoad) {
          angular.forEach(dependentFiles, function (filePath, index) {
            dependentFiles[index] = filePath.replace('${theme}', routerService.getTheme());
          });
          return $ocLazyLoad.load(dependentFiles, {
            cache: true
          });
        }
        layoutConfigFn.$inject = ['$rootScope', '$q', 'Constants', 'ajaxServiceFactory', 'storageService'];
        function layoutConfigFn($rootScope, $q, Constants, ajaxServiceFactory, storageService) {
          var url = layoutConfig, ajaxService, siteInfo, defer = $q.defer();
          if (!url) {
            return $q.resolve({});
          }
          siteInfo = storageService.getSiteInfo();
          if (options.params && options.params.siteCode && siteInfo && siteInfo.siteCode && options.params.siteCode != siteInfo.siteCode) {
            url = url + "/" + options.params.siteCode;
          }
          ajaxService = ajaxServiceFactory.buildAjaxService({
            loadConfig: {
              'url': url,
              'method': 'post',
              'cache': cacheLayout
            }
          });
          var params = {};
          if (options.params && options.params.parmCat)
            params.parmCat = options.params.parmCat;
          if (options.params && options.params.parmSubcat)
            params.parmSubcat = options.params.parmSubcat;
          ajaxService.loadConfig(params).then(function (response) {
            defer.resolve(response ? response.data : {});
          }, function (error) {
            log.debug('can not load config[' + url + ']:' + error);
            defer.reject();
          });
          return defer.promise;
        }

        i18nConfigFn.$inject = ['$rootScope', '$q', 'Constants', 'storageService', 'ajaxServiceFactory'];
        function i18nConfigFn($rootScope, $q, Constants, storageService, ajaxServiceFactory) {
          var ajaxService, defer = $q.defer();
          if (!i18nConfig) {
            return $q.resolve({});
          }
          ajaxService = ajaxServiceFactory.buildAjaxService({
            loadConfig: {
              'url': i18nConfig,
              'method': 'get',
              'cache': cacheResource
            }
          });
          ajaxService.loadConfig().then(function (response) {
            defer.resolve(loadResource($rootScope, Constants.NOTIFY_CHANGE_LANGUAGE, Constants.SESSION_I18N_RESOURES, storageService, response ? response.data : null));
          }, function error(error) {
            log.debug('can not load config[' + url + ']:' + error);
            defer.reject();
          });

          return defer.promise;
        }

        authorizationConfigFn.$inject = ['$rootScope', '$q', '$stateParams', 'Constants', 'ajaxServiceFactory'];
        function authorizationConfigFn($rootScope, $q, $stateParams, Constants, ajaxServiceFactory) {
          var ajaxService, defer = $q.defer();
          if (!authorizationConfig) {
            return $q.resolve({});
          }
          ajaxService = ajaxServiceFactory.buildAjaxService({
            loadConfig: {
              'url': authorizationConfig,
              'method': 'get',
              'cache': cacheAuthorization
            }
          });
          ajaxService.loadConfig().then(function (response) {
            $stateParams.authorization = buildAuthService($rootScope, Constants, ajaxServiceFactory, response ? response.data : {});
            defer.resolve($stateParams.authorization);
          }, function error(error) {
            log.debug('can not load config[' + url + ']:' + error);
            defer.reject();
          });
          return defer.promise;
        }

        validatorConfigFn.$inject = ['$rootScope', '$q', 'Constants', 'storageService', 'ajaxServiceFactory'];
        function validatorConfigFn($rootScope, $q, Constants, storageService, ajaxServiceFactory) {
          var ajaxService, defer = $q.defer();
          if (!validatorConfig) {
            return $q.resolve({});
          }
          ajaxService = ajaxServiceFactory.buildAjaxService({
            loadConfig: {
              'url': validatorConfig,
              'method': 'get',
              'cache': cacheValidationRule
            }
          });
          ajaxService.loadConfig().then(function (response) {
            var resources = (response && response.data) ? response.data.resources : null;
            if (resources) {
              loadResource($rootScope, Constants.NOTIFY_CHANGE_LANGUAGE, Constants.SESSION_I18N_VALIDATION_RESOURES, storageService, resources);
            }
            defer.resolve((response && response.data) ? (response.data.rules || {}) : {});
          }, function error(error) {
            log.debug('can not load config[' + url + ']:' + error);
            defer.reject();
          });

          return defer.promise;
        }

        function buildAuthService($rootScope, Constants, ajaxServiceFactory, authorizationConfig) {
          var authorizationServices = {}, authService, emptyServiceNames = [];
          angular.forEach(authorizationConfig, function (value, key) {
            if (value == '') {
              emptyServiceNames.push(key);
            } else {
              authorizationServices[key] = {
                url: 'do/' + value,
                method: 'post',
                cache: true
              };
            }
          });
          authService = ajaxServiceFactory.buildAjaxService(authorizationServices) || {};
          angular.forEach(emptyServiceNames, function (value, key) {
            authService[value] = angular.noop;
          });
          return authService;
        }

        function loadResource($rootScope, notifyType, resourceType, storageService, resources) {
          if (resources) {
            storageService.setItemToSession(resourceType, resources);
            $rootScope.$emit(notifyType);
          }
          return resources;
        }

        options.title = options.title || (dialogsModule.title || 'title.dialogs.lookup');
        options.params = options.params || {};
        options.btnCallback = options.btnCallback || {};
        if (!options.size) {
          delete options.size;
        }
        angular.merge(dialogsModule, options);
        dialogsModule.size = dialogsModule.size || [800, 500];
        dialogsModule.level = options.level || 'info';
        dialogsModule.icon = options.icon || 'regular';
        if (dialogsModule.size && angular.isArray(dialogsModule.size)) {
          dialogsModule.bodyStyle = {
            width: dialogsModule.size[0] + 'px',
            height: dialogsModule.size[1] + 'px'
          };
        }
        defaultOption = {
          templateUrl: options.templateUrl || 'pti/template/modal/custormer.html',
          size: dialogsModule.size,
          controller: dialogsModule.controller,
          controllerAs: dialogsModule.controllerAs,
          windowTopClass: options.windowTopClass,
          animation: options.animation === undefined ? true : options.animation,
          resolve: {
            dialogsModule: function () {
              return dialogsModule;
            },
            dependentFiles: dependentFileFn,
            layoutConfig: layoutConfigFn,
            i18nConfig: i18nConfigFn,
            authService: authorizationConfigFn,
            validatorConfig: validatorConfigFn
          }
        };
        modalOptions = angular.extend({}, provider.modalOptions, defaultOption);
        modalOptions.blocked = true;
        dialogsInstance = openModalDialogs(modalOptions);
        return dialogsInstance;
      }
      return {
        openLoading: openLoading,
        closeLoading: closeLoading,
        openModalDialogs: openModalDialogs,
        openDialogs: openDialogs,
        openAcknowledgeDialogs: openAcknowledgeDialogs,
        openJumpDialogs: openJumpDialogs,
        openWarningDialogs: openWarningDialogs,
        openInfoDialogs: openInfoDialogs,
        openSuccessDialogs: openSuccessDialogs,
        openErrorDialogs: openErrorDialogs,
        openConfirmDialogs: openConfirmDialogs,
        openPromptDialogs: openPromptDialogs,
        openLogDialogs: openLogDialogs,
        openCustomDialogs: openCustomDialogs
      };
    }
  }

	/*
	 * angular.module("uib/template/modal/window.html").run(["$templateCache", function($templateCache) { $templateCache.put("uib/template/modal/window.html", '' + '<div class="modal-dialog
	 * {{angular.isString(size) ? \'modal-\' + size : \'\'}}"' + '<div class="modal-content" uib-modal-transclude></div></div>\n' + ''); }]);
	 */

  $templateCache.$inject = ["$templateCache"];
  function $templateCache($templateCache) {
    $templateCache.put('pti/template/modal/acknowledge.html', '' +
      '<div class="acknowledgeDialog app-modal-content {{vm.dialogsOptions.level}}">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button><i ng-show="vm.dialogsOptions.icon" class="icon icon-{{vm.dialogsOptions.icon}}"></i><label class="modal-title" id="modal-title">{{vm.title|translate}}</label>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel jumbotron" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '             <div ng-repeat="message in vm.messages"><i class="icon icon-{{vm.dialogsOptions.icon}}"></i><span>{{message | translate }}</span></div>\n' +
      '             <div ng-show="vm.redirections && vm.redirections.length > 0"><label>Goto:</label> <a href="#" ng-click="vm.redirect(redirection)" ng-repeat="redirection in vm.redirections"><span>{{redirection.name | translate }}</span></a></div>\n' +
      '    </div>\n' +
      '    <div class="modal-footer">\n' +
      '        <fs-button fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.closeButtons"/>\n' +
      '    </div>\n' +
      '</div>\n');

    $templateCache.put('pti/template/modal/jump.html', '' +
      '<div class="acknowledgeDialog app-modal-content {{vm.dialogsOptions.level}}">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button><i ng-show="vm.dialogsOptions.icon" class="icon icon-{{vm.dialogsOptions.icon}}"></i><label class="modal-title" id="modal-title">{{vm.title|translate}}</label>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel jumbotron" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '             <div ng-repeat="message in vm.messages"><span>{{message | translate }}</span></div>\n' +
      '             <div><label>Goto:</label> <a href="#" ng-click="vm.jump(redirection)" ng-repeat="redirection in vm.redirections"><span>{{redirection.name | translate }}</span></a></div>\n' +
      '    </div>\n' +
      '    <div class="modal-footer btn-group-sm">\n' +
      '        <fs-button fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.closeButtons"/>\n' +
      '    </div>\n' +
      '</div>\n');

    $templateCache.put('pti/template/modal/messages.html', '' +
      '<div class="messageDialog app-modal-content {{vm.dialogsOptions.level}}" ng-click="vm.dialogsOptions.cancelAutoClose = true;">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button>\n' +
      '        <i ng-show="vm.dialogsOptions.icon" class="icon icon-{{vm.dialogsOptions.icon}}"></i>\n' +
      '        <span class="modal-title" id="modal-title">{{vm.title|translate}}</span>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '         <ul class="list-unstyled">\n' +
      '             <li ng-repeat="message in vm.messages"><span ng-bind-html="message | translate | trustedHtml"></span></li>\n' +
      '         </ul>\n' +
      '    </div>\n' +
      '    <div class="modal-footer btn-group-sm" ng-if="!vm.dialogsModule.autoClose">\n' +
      '        <fs-button ng-if="vm.dialogsOptions.bottomOkBtn" fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.okButtons"/>\n' +
      '        <fs-button ng-if="!vm.dialogsOptions.bottomOkBtn" fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.closeButtons"/>\n' +
      '    </div>\n' +
      '</div>\n');
    $templateCache.put('pti/template/modal/logMessages.html', '' +
      '<div class="logDialog app-modal-content {{vm.dialogsOptions.level}}">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button><label class="modal-title" id="modal-title">{{vm.title|translate}}</label>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '       <textarea class="form-control input-sm" rows="20"><span>{{::vm.messages}}</span></textarea>\n' +
      '    </div>\n' +
      '    <div class="modal-footer btn-group-sm">\n' +
      '        <fs-button fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.closeButtons"/>\n' +
      '    </div>\n' +
      '</div>\n');

    $templateCache.put('pti/template/modal/confirmMessages.html', '' +
      '<div class="confirmDialog app-modal-content {{vm.dialogsOptions.level}}">\n' +
      '    <div class="modal-header">\n' +
      '       <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button><i ng-show="vm.dialogsOptions.icon" class="icon icon-{{vm.dialogsOptions.icon}}"></i><span class="modal-title" id="modal-title">{{vm.title|translate}}</span>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '         <ul class="list-unstyled">\n' +
      '             <li ng-repeat="message in vm.messages"><span>{{message | translate }}</span></li>\n' +
      '         </ul>\n</b>' +
      '    </div>\n' +
      '    <div class="modal-footer">\n' +
      '        <fs-button fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.okAndCloseButtons"/>\n' +
      '    </div>\n' +
      '</div>\n');

    $templateCache.put('pti/template/modal/promptInput.html', '' +
      '<div class="promptInputDialog app-modal-content {{vm.dialogsOptions.level}}">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close()"><span aria-hidden="true" class="icon icon-close"></span></button><i ng-show="vm.dialogsOptions.icon" class="icon icon-{{vm.dialogsOptions.icon}}"></i><span class="modal-title" id="modal-title">{{vm.title|translate}}</span>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel" id="modal-body" ng-style="vm.dialogsOptions.bodyStyle">\n' +
      '       <div class="panel-body"><textarea class="form-control input-sm" rows="5" ng-model="vm.promptMessage"></textarea></div>\n' +
      '    </div>\n' +
      '    <div class="modal-footer">\n' +
      '		 <fs-button fs-button-config="button" fs-button-group="true" ng-repeat="button in vm.promptOkAndCloseButtons"/>' +
      '    </div>\n' +
      '</div>\n');

    $templateCache.put('pti/template/modal/custormer.html', '' +
      '<div ng-form name="{{::vm.formName}}" disableUnloadCheck="{{::vm.disableUnloadCheck}}" class="custormerDialog app-modal-content {{vm.dialogsModule.level}}">\n' +
      '    <div class="modal-header">\n' +
      '        <button type="button" class="close" data-dismiss="alert" aria-label="Close" ng-click="vm.close != undefined ? vm.close() : vm.ok()"><span aria-hidden="true" class="icon icon-close"></span></button><i ng-show="vm.dialogsModule.icon" class="icon icon-{{vm.dialogsModule.icon}}"></i><span class="modal-title" id="modal-title">{{vm.dialogsModule.title|translate}}</span>\n' +
      '    </div>\n' +
      '    <div class="modal-body panel" id="modal-body" ng-style="vm.dialogsModule.bodyStyle">\n' +
      '         <div ng-include="vm.dialogsModule.templateUrl"></div>\n' +
      '    </div>\n' +
      '    <div class="modal-footer">\n' +
      '        <button class="btn btn-default" type="button" ng-if="vm.close != undefined" ng-click="vm.close()"><span class="icon icon-close"></span><span>{{"button.text.close"|translate}}</span></button>\n' +
      '        <button class="btn btn-primary" type="button" ng-if="vm.ok != undefined" ng-click="vm.dialogsModule.disableButton($event);vm.ok()"><span class="icon icon-ok"></span><span>{{"button.text.ok"|translate}}</span></button>\n' +
      '    </div>\n' +
      '</div>\n');
    $templateCache.put('pti/template/modal/dashboard/panel.html', '' +
      '<div class="custormerDialog">\n' +
      '    <div class="modal-content" id="modal-body" ng-style="panelController.panelConfig.bodyStyle" ng-include="panelController.panelConfig.dashboardTemplateUrl">\n' +
      '    </div>\n' +
      '</div>\n');
  }
})(angular);
